package com.yue92.datalife.controller.v1;

import com.yue92.datalife.common.CodeEnum;
import com.yue92.datalife.common.CommonUtil;
import com.yue92.datalife.common.GroupCreate;
import com.yue92.datalife.common.GroupUpdate;
import com.yue92.datalife.exception.UncheckedException;
import com.yue92.datalife.helper.RecordHelper;
import com.yue92.datalife.model.Record;
import com.yue92.datalife.model.User;
import com.yue92.datalife.response.*;
import com.yue92.datalife.service.IRecordItemService;
import com.yue92.datalife.service.IRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;

import static com.yue92.datalife.common.Constant.CURRENT_USER_ATTRIBUTE;

@RestController
@RequestMapping(value = "/api/v1/records", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class RecordController {

    @Autowired
    private RecordHelper recordHelper;

    @Autowired
    private IRecordService recordService;

    @Autowired
    private IRecordItemService recordItemService;

    @GetMapping("")
    public ResponseResource<RecordIndexRes> index(@RequestAttribute(CURRENT_USER_ATTRIBUTE) User currentUser) {

        return ResponseResource.success(recordHelper.index(currentUser));
    }

    @GetMapping("/week")
    public ResponseResource<RecordWeekRes> week(@RequestParam("record_id") Long recordId, @RequestParam(value = "record_date", required = false) String recordDate, @RequestParam(value = "week_offset", required = false) Integer weekOffset, @RequestAttribute(CURRENT_USER_ATTRIBUTE) User currentUser) {
        Record record = recordHelper.checkAndGetRecord(recordId, currentUser);
        LocalDate date = CommonUtil.getLocalDate(recordDate, weekOffset, ChronoUnit.WEEKS);

        return ResponseResource.success(recordHelper.week(record, date));
    }

    @GetMapping("/month")
    public ResponseResource<RecordMonthRes> month(@RequestParam("record_id") Long recordId, @RequestParam(value = "record_date", required = false) String recordDate, @RequestParam(value = "month_offset", required = false) Integer monthOffset, @RequestAttribute(CURRENT_USER_ATTRIBUTE) User currentUser) {
        Record record = recordHelper.checkAndGetRecord(recordId, currentUser);
        LocalDate date = CommonUtil.getLocalDate(recordDate, monthOffset, ChronoUnit.MONTHS);

        return ResponseResource.success(recordHelper.month(record, date));
    }

    @PostMapping("")
    public ResponseResource<?> create(@Validated({GroupCreate.class}) @RequestBody RecordRes recordRes, @RequestAttribute(CURRENT_USER_ATTRIBUTE) User currentUser) {
        Record record = new Record();
        record.setUserId(currentUser.getId());
        record.setName(recordRes.getName());
        record.setComment(recordRes.getComment());
        record.setAllowCumulate(recordRes.getAllowCumulate());
        record.setSort(recordRes.getSort());
        record.setDisplay(true);

        recordService.save(record);

        return ResponseResource.success(new HashMap<String, Object>() {{
            put("id", record.getId());
        }});
    }

    @PutMapping("/{id}")
    public ResponseResource<?> update(@PathVariable("id") Long id, @Validated({GroupUpdate.class}) @RequestBody RecordRes recordRes, @RequestAttribute(CURRENT_USER_ATTRIBUTE) User currentUser) {
        Record record = recordHelper.checkAndGetRecord(id, currentUser);

        record.setName(recordRes.getName());
        record.setComment(recordRes.getComment());
        record.setAllowCumulate(recordRes.getAllowCumulate());
        record.setSort(recordRes.getSort());

        recordService.save(record);

        return ResponseResource.success();
    }

    @DeleteMapping("/{id}")
    public ResponseResource<?> delete(@PathVariable("id") Long id, @RequestAttribute(CURRENT_USER_ATTRIBUTE) User currentUser) {
        Record record = recordHelper.checkAndGetRecord(id, currentUser);

        if (recordItemService.existsByRecordId(id)) {
            throw new UncheckedException(CodeEnum.FAILURE, "has child data");
        }

        recordService.remove(record.getId());

        return ResponseResource.success();
    }
}
